import {createStore,Commit} from 'vuex'

import axios, { AxiosRequestConfig } from 'axios';
import Login from './views/Login.vue';
export interface ResponseType<P = object > {
    code:number;
    msg:string;
    data:P;
}
export interface GlobalErrorProps {
    status:boolean;
    message?:string;
}
export interface UserProps{
    isLogin:boolean;
    nickName?:string;
    _id?:string;
    column?:string;
    email?:string;
    avatar?:ImageProps;
    description?:string
}
export interface GlooalDataProps{
    token:string;
    loading:boolean;
    columns:ColumnProps[],
    posts:PostProps[];
    user:UserProps;
    error:GlobalErrorProps


}
export interface ImageProps{
    _id?:string;
    url?:string;
    createdAt?:string;
    fitUrl?: string;
}
export interface ColumnProps {
    _id: string;
    title: string;

    description: string;
    avatar?: ImageProps;
}
export interface PostProps {
    _id?:string;
    title:string;
    excerpt?:string;
    content:string;
    image?:ImageProps | string;
    createdAt?:string;
    column:string;
    author?:string | UserProps;
    isHTML?:string
    isLiked?:boolean;
    isCollected?:boolean;
    likes?:number;
    collects?:number;
    comments?:number;
}
const getAndCommit = async(url:string,mutationsName:string,commit:Commit) =>{
    // commit('setLoading',true)
    const { data } = await axios.get(url)
    // await new Promise(resolve => setTimeout(resolve,3000))
    commit(mutationsName,data)
    // commit('setLoading',false)
    return data


}
const postAndCommit = async(url:string,mutationsName:string,commit:Commit,paload:any) =>{
    // commit('setLoading',true)
    const { data } = await axios.post(url,paload)
    // await new Promise(resolve => setTimeout(resolve,3000))
    commit(mutationsName,data)
    commit('setLoading',false)
    return data

}

const asyncAndCommit = async(url:string,mutationName:string,commit:Commit,config:AxiosRequestConfig={method:'get'})=>{
    const { data}  = await axios(url,config)
    commit(mutationName,data)
    return data
}

const store = createStore<GlooalDataProps>({
    state:{
        error:{status:false},
        token:localStorage.getItem('token') || '',
        loading:false,
        columns:[],
        posts:[],
        user:{
            isLogin :false,
        }

    },
    mutations:{
        // login(state){
        //     state.user ={
        //         ...state.user ,isLogin:true,name:'cliu'
        //     }
        // },
        createPost(state,newPost){
            state.posts.push(newPost)
        },
        fetchColumns(state,rawData){
           
            state.columns=rawData.data.list


            
        },
        fetchColumn(state,rawData){
            state.columns=[rawData.data]
        },
        fetchPosts(state,rawData){
            state.posts=rawData.data.list
        },
        setLoading(state,status){
            state.loading=status
        },
        setError(state,e:GlobalErrorProps){
            state.error=e
            

        },
        fetchCurrentUser(state,rawData){
            state.user = { isLogin:true ,...rawData.data}
        },
        login(state,rawData){
            const {token}= rawData.data
            state.token= token
            localStorage.setItem('token',token)
            axios.defaults.headers.common['Authorization']=`Bearer ${token}`

        },
        logout(state){
            state.token = ''
            localStorage.removeItem('token')
            delete axios.defaults.headers.common['Authorization'] 
            state.user={isLogin:false}
        },
        fetchPostDetail(state,rawData){
            
            state.posts = [rawData.data]
            // console.log('2',state.posts )

        },
        deletePost(state,{data}){
            state.posts = state.posts.filter(post => post._id!==data._id)
        },
        updatePost(state,{data}){
            state.posts = state.posts.map(post =>{
                if(post._id === data._id){
                    return data
                }else{
                    return post
                }
            })
        },
        updateUser(state,{data}){
            state.user = {...state.user,...data}
        }
        


    },
    actions:{
        fetchColumns({commit}){
            return getAndCommit('/columns','fetchColumns',commit)
          
           
        },
       fetchColumn({commit},cid){
         return getAndCommit(`/columns/${cid}`,'fetchColumn',commit)
           
        },
       fetchPosts({commit},cid){
          return getAndCommit(`/columns/${cid}/posts`,'fetchPosts',commit)
        
        },
        fetchCurrentUser({commit}){
           return getAndCommit('/user/current','fetchCurrentUser',commit)
        },
        login({commit},payload){
           return  postAndCommit('/user/login','login',commit,payload)
        },
        createPost({commit},payload){
            return  postAndCommit('/posts','createPost',commit,payload)
         },
        //  create({commit},payload){
        //     return  postAndCommit('/posts','create',commit,payload)
        //  },
        loginAndFetch({dispatch},loginData){
            return dispatch('login',loginData).then(()=>{
               return  dispatch('fetchCurrentUser')
            })
        },
        fetchPostDetail({commit},id){
            
            return getAndCommit(`/posts/${id}`,'fetchPostDetail',commit)
        },
        updatePost({ commit }, { id, payload }) {
            return asyncAndCommit(`/posts/${id}`, 'updatePost', commit, {
              method: 'patch',
              data: payload
            })
          },
        updateUser({ commit },{ id,payload}) {
            return asyncAndCommit(`/user/${id}`, 'updateUser', commit, {
              method: 'patch',
              data:payload         
            })
          },
        deletePost({ commit }, id) {
            return asyncAndCommit(`/posts/${id}`, 'deletePost', commit, { method: 'delete' })
          },
        


    },
    getters:{
        getColumnById:(state=>(id:string)=>{
            return state.columns.find(c=>c._id ===id)
        }),
        getPostsByCid:(state)=>(cid:string)=>{
            return state.posts.filter(post=>post.column === cid)
        },
        getCurrentPost:(state)=>(id:string)=>{
            // console.log('3',state.posts.find(post => post._id === id))
            return state.posts.find(post => post._id === id)
        }
    }
})

export default store